package com.tangding.service.db;

import java.io.Serializable;
import java.util.List;

import org.bson.Document;
import org.bson.conversions.Bson;

import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.tangding.common.exception.GException;
import com.tangding.common.logx.LogHelp;
import com.tangding.common.tools.ErrorConstants;

/**
 * @author Ranger
 * @version 2017年8月24日_下午12:00:31
 * @description
 */
public interface MongoRepository<ID extends Serializable> {

    default Document findOne(MongoClient client, MongoDBOption option, ID id) throws GException {
        try {
        	Document condition = new Document();
            condition.put("_id", id);
            return findOne(client, option, condition);
        } catch (Exception e) {
            LogHelp.doLogException(e);
            throw new GException(ErrorConstants.ERR_DB);
        }
    }

    default Document findOne(MongoClient client, MongoDBOption option, Bson condition) throws GException {
        try {
            FindIterable<Document> documents = MongoDBUtil.find(client, option, condition).limit(1);
            return documents.first();
        } catch (Exception e) {
            LogHelp.doLogException(e);
            throw new GException(ErrorConstants.ERR_DB);
        }
    }

    default FindIterable<Document> findMany(MongoClient client, MongoDBOption option, Bson condition, int skip, int limit) throws GException {
        try {
            return MongoDBUtil.find(client, option, condition).skip(skip).limit(limit);
        } catch (Exception e) {
            LogHelp.doLogException(e);
            throw new GException(ErrorConstants.ERR_DB);
        }
    }

    default FindIterable<Document> findAll(MongoClient client, MongoDBOption option, Bson condition) throws GException {
        try {
            return MongoDBUtil.find(client, option, condition);
        } catch (Exception e) {
            LogHelp.doLogException(e);
            throw new GException(ErrorConstants.ERR_DB);
        }
    }
    
    default FindIterable<Document> findMany(MongoClient client, MongoDBOption option, Bson condition, int skip, int limit, Bson sort) throws GException {
        try {
            return MongoDBUtil.find(client, option, condition).skip(skip).limit(limit).sort(sort);
        } catch (Exception e) {
            LogHelp.doLogException(e);
            throw new GException(ErrorConstants.ERR_DB);
        }
    }

    default FindIterable<Document> findAll(MongoClient client, MongoDBOption option, Bson condition, Bson sort) throws GException {
        try {
            return MongoDBUtil.find(client, option, condition).sort(sort);
        } catch (Exception e) {
            LogHelp.doLogException(e);
            throw new GException(ErrorConstants.ERR_DB);
        }
    }

    default void delete(MongoClient client, MongoDBOption option, ID id) throws GException {
        try {
        	Document condition = new Document();
            condition.put("_id", id);
            delete(client, option, condition);
        } catch (Exception e) {
            LogHelp.doLogException(e);
            throw new GException(ErrorConstants.ERR_DB);
        }
    }

    default void delete(MongoClient client, MongoDBOption option, Bson condition) throws GException {
        try {
            MongoDBUtil.remove(client, option, condition);
        } catch (Exception e) {
            LogHelp.doLogException(e);
            throw new GException(ErrorConstants.ERR_DB);
        }
    }

    default void deleteMany(MongoClient client, MongoDBOption option, Bson condition) throws GException {
        try {
            MongoDBUtil.removeMany(client, option, condition);
        } catch (Exception e) {
            LogHelp.doLogException(e);
            throw new GException(ErrorConstants.ERR_DB);
        }
    }

    default void save(MongoClient client, MongoDBOption option, Document doc) throws GException {
        try {
            MongoDBUtil.insert(client, option, doc);
        } catch (Exception e) {
            LogHelp.doLogException(e);
            throw new GException(ErrorConstants.ERR_DB);
        }
    }

    default void saveMany(MongoClient client, MongoDBOption option, List<Document> docs) throws GException {
        try {
            MongoDBUtil.insertMany(client, option, docs);
        } catch (Exception e) {
            LogHelp.doLogException(e);
            throw new GException(ErrorConstants.ERR_DB);
        }
    }

    default void update(MongoClient client, MongoDBOption option, Document data, Bson condition) {
        updateDocument(client, option, data, condition);
    }

    default void updateDocument(MongoClient client, MongoDBOption option, Document data, Bson condition) {
        MongoDBUtil.update(client, option, data, condition);
    }
    
    default void updateMany(MongoClient client, MongoDBOption option, Document data, Bson condition) {
        updateDocumentMany(client, option, data, condition);
    }

    default void updateDocumentMany(MongoClient client, MongoDBOption option, Document data, Bson condition) {
        MongoDBUtil.updateMany(client, option, data, condition);
    }

    default void replace(MongoClient client, MongoDBOption option, Document data, Bson condition) {
        replaceDocument(client, option, data, condition);
    }

    default void replaceDocument(MongoClient client, MongoDBOption option, Document data, Bson condition) {
        MongoDBUtil.replace(client, option, data, condition);
    }
}
